package kingwing.dc.core.orm.hibernate;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

import kingwing.dc.core.model.BaseEntity;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Session;

import com.bstek.bdf2.core.business.IDept;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.orm.hibernate.HibernateDao;
import com.bstek.bdf2.core.orm.hibernate.ISessionCallback;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Junction;
import com.bstek.dorado.data.provider.filter.SingleValueFilterCriterion;
import com.bstek.dorado.util.proxy.ProxyBeanUtils;

/**
 * Hibernate操作的基础类，所有的支持Hibernate操作的业务类（非BDF2底层类）都可以继承该类
 * 
 * @author Louis
 * 
 */
@SuppressWarnings("unused")
public abstract class AbstractHibernateDao extends HibernateDao {

	/**
	 * 根据ID加载某个实体对象
	 * 
	 * @param id
	 * @param clazz
	 * @return
	 */
	public <T> T get(final Serializable id, final Class<T> clazz) {
		return (T) this.doInHibernateSession(new ISessionCallback<T>() {

			@SuppressWarnings("unchecked")
			@Override
			public T doInSession(Session session) {
				return (T) session.get(clazz, id);
			}

		});
	}

	/**
	 * 依据当前用户保存一个实体对象
	 * 
	 * @param entity
	 * @return
	 */
	public Serializable save(final BaseEntity entity) {
		return this.doInHibernateSession(new ISessionCallback<Serializable>() {

			@Override
			public Serializable doInSession(Session session) {
				entity.setCreateUser(ContextHolder.getLoginUser().getCname());
				entity.setCreateUserId(ContextHolder.getLoginUser().getUsername());
				entity.setCreateDate(new Date());
				return session.save(entity);
			}

		});
	}
	/**
	 * 依据当前用户保存一个实体对象
	 * 
	 * @param entity
	 * @return
	 */
	public Serializable saveNotUser(final BaseEntity entity) {
		return this.doInHibernateSession(new ISessionCallback<Serializable>() {
			
			@Override
			public Serializable doInSession(Session session) {
				entity.setCreateUser(ContextHolder.getLoginUser().getCname());
				entity.setCreateDate(new Date());
				return session.save(entity);
			}
			
		});
	}

	/**
	 * 依据当前用户更新一个实体对象
	 * 
	 * @param entity
	 */
	public void update(final BaseEntity entity) {
		this.doInHibernateSession(new ISessionCallback<Void>() {

			@Override
			public Void doInSession(Session session) {
				entity.setUpdateDate(new Date());
				entity.setUpdateUser(ContextHolder.getLoginUser().getCname());
				session.update(entity);
				return null;
			}

		});
	}

	/**
	 * 删除一个实体对象。
	 * 
	 * @param entity
	 */
	public void delete(final BaseEntity entity) {
		this.doInHibernateSession(new ISessionCallback<Void>() {

			@Override
			public Void doInSession(Session session) {
				session.delete(entity);
				return null;
			}

		});
	}

	/**
	 * 根据ID和全限定类名删除一个实体对象。
	 * 
	 * @param id
	 * @param className
	 *            该类必须是gov.pbc.nn.core.entity.BaseEntity的子类
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public void delete(final String id, String className) throws Exception {
		final Class<?> clazz = Class.forName(className);
		if (BaseEntity.class.isAssignableFrom(clazz)) {
			this.delete(id, (Class<? extends BaseEntity>) clazz);
		}
	}

	/**
	 * 根据ID和Class删除一个实体对象。
	 * 
	 * @param id
	 * @param clazz
	 *            Class所表示的类必须是gov.pbc.nn.core.entity.BaseEntity的子类
	 */
	public void delete(final String id, final Class<? extends BaseEntity> clazz) {
		this.doInHibernateSession(new ISessionCallback<Void>() {

			@Override
			public Void doInSession(Session session) {
				Class<?> type = clazz;
				if (ProxyBeanUtils.isProxy(clazz)) {
					type = ProxyBeanUtils.getProxyTargetType(clazz);
				}
				BaseEntity entity = (BaseEntity) session.get(type, id);
				if (entity != null) {
					session.delete(entity);
				}
				return null;
			}

		});
	}

	public int executeUpdate(final String hql, final Map<String, Object> params) {
		return this.doInHibernateSession(new ISessionCallback<Integer>() {

			@Override
			public Integer doInSession(Session session) {
				if (params == null || params.isEmpty()) {
					return session.createQuery(hql).executeUpdate();
				}
				return session.createQuery(hql).setProperties(params).executeUpdate();
			}

		});
	}
	
	
	
}
